package bg.consulting.labo;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;

import javax.media.Control;
import javax.media.Controller;
import javax.media.ControllerEvent;
import javax.media.ControllerListener;
import javax.media.Format;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.Player;
import javax.media.Processor;
import javax.media.ProcessorModel;
import javax.media.Time;
import javax.media.bean.playerbean.MediaPlayer;
import javax.media.control.FormatControl;
import javax.media.control.MpegAudioControl;
import javax.media.format.AudioFormat;
import javax.media.protocol.ContentDescriptor;
import javax.media.protocol.DataSource;
import javax.media.protocol.FileTypeDescriptor;
import javax.media.protocol.SourceCloneable;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import bg.consulting.labo.util.UtilJMF;
import bg.consulting.labo.util.UtilSwing;

/**
 * Classe de test et de demo de mediaPlayer 
 * Permet de lire du Mp3
 * 
 * @author Bertrand
 * 
 */

public class FileMediaPlayer implements IDataSourceProvider {
	private JPanel panelGlobal = new JPanel();
	private JPanel pMediaPlayer = new JPanel();
	private File file = new File("C:\\musique\\test.mp3");
	private MediaPlayer mediaPlayer;
	private JSlider sliderPosition = new JSlider();
	private JSlider sliderVolume = new JSlider();
	private ThreadPosition threadPosition = null;
	private long timeStart = 0;
	private JFrame frame;
	private JButton buttonStart = new JButton("Start");
	private JButton buttonStop = new JButton("Pause");
	private DataSource dataSource;

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		System.out.println("Test MainGUI Mediaplayer");
		JFrame frame = new JFrame();
		FileMediaPlayer fileMediaPlayer = new FileMediaPlayer();
		frame.add(fileMediaPlayer.getPanelGlobal());
		UtilSwing.initFrame(frame);
		fileMediaPlayer.start();
		Thread.sleep(100);
		UtilJMF.waitUntilRealize(fileMediaPlayer.mediaPlayer);
		fileMediaPlayer.getFormat();
		frame.pack();

	}

	public FileMediaPlayer() {
		this(new JFrame());

	}

	public FileMediaPlayer(JFrame frame) {
		this.frame = frame;
		initFrame();
	}

	private void initFrame() {
		try {
			JPanel p = new JPanel();
			JLabel label = new JLabel("----------");
			label.setPreferredSize(new Dimension(350, 60));
			this.pMediaPlayer.add(label);
			this.sliderVolume.setOrientation(JSlider.VERTICAL);
			this.sliderVolume.setPreferredSize(new Dimension(30, 60));
			buttonStart.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					start();
				}
			});

			buttonStop.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					if (mediaPlayer == null) {
					} else {
						mediaPlayer.stop();
					}
					buttonStart.setEnabled(true);
					buttonStop.setEnabled(false);
				}
			});
			buttonStop.setEnabled(false);
			p.add(buttonStart);
			p.add(buttonStop);
			p.add(this.pMediaPlayer);

			panelGlobal.add(p);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private void start() {
		if (this.mediaPlayer == null) {
			if (this.threadPosition != null) {
				threadPosition.stop();
			}
			threadPosition = new ThreadPosition();
		} else {
			this.mediaPlayer.start();
		}
		buttonStart.setEnabled(false);
		buttonStop.setEnabled(true);
	}

	public void openMediaPlayer() {
		try {
			String nameUrl = "" + this.file.toURI();
			boolean boolResult;
			String audioEffect = null;
			String videoEffect = null;

			// mediaPlayer = jmapps.util.JMFUtils.createMediaPlayer(nameUrl,
			// (Frame) this.frame, audioEffect, videoEffect);
			MediaLocator mediaLocator = new MediaLocator(nameUrl);
			this.dataSource = Manager.createDataSource(mediaLocator);
			mediaPlayer = jmapps.util.JMFUtils.createMediaPlayer(this.dataSource, this.frame);
			Player player = mediaPlayer.getPlayer();
			player.addControllerListener(new ControllerListener() {

				@Override
				public void controllerUpdate(ControllerEvent event) {
					System.out.println("ControllerEvent state:" + event.getSourceController().getState() + "  " + event.getSourceController().getMediaTime() + "  realized: " + Controller.Realized);
				}
			});
			mediaPlayer.start();
			Thread.sleep(1000);

			this.pMediaPlayer.removeAll();
			this.pMediaPlayer.add(mediaPlayer.getControlPanelComponent());
			this.pMediaPlayer.add(this.sliderVolume);
			this.pMediaPlayer.add(this.sliderPosition);

			sliderPosition.addMouseListener(new MouseListener() {
				public void mouseReleased(MouseEvent e) {
					try {
						System.out.println("mouseReleasedBBB   value: " + sliderPosition.getValue());
						int value = sliderPosition.getValue();
						Player player = mediaPlayer.getPlayer();

						double dureeTotale = player.getDuration().getSeconds();

						double seconds = value * dureeTotale / 100.0;
						Time now = new Time(seconds);
						mediaPlayer.setMediaTime(now);

						System.out.println("MousePressedAAA  value: " + value);

					} catch (Exception e1) {
						e1.printStackTrace();
					}
					threadPosition.setUpdatePosition(true);
				}

				public void mousePressed(MouseEvent e) {
					threadPosition.setUpdatePosition(false);
				}

				public void mouseExited(MouseEvent e) {
				}

				public void mouseEntered(MouseEvent e) {
				}

				public void mouseClicked(MouseEvent e) {
				}
			});
			sliderVolume.addChangeListener(new ChangeListener() {
				public void stateChanged(ChangeEvent e) {
					changeVolume();
				}
			});
			for (Control control : player.getControls()) {
				System.out.println("-> Control :" + control);

				// pMediaPlayer.add(control.getControlComponent());
			}

			// Component visualComponent = mediaPlayer.getVisualComponent();
			// System.out.println( "VisualComponent : "+visualComponent);
			panelGlobal.updateUI();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public JPanel getPanelGlobal() {
		return panelGlobal;
	}

	public Format getFormat() {
		FormatControl fc = (FormatControl) this.mediaPlayer.getPlayer().getControl(FormatControl.class.getName());

		System.out.println("getFormat " + fc);
		Format format = null;
		if (fc == null) {
		} else {
			format = fc.getFormat();

		}
		MpegAudioControl fcMpeg = (MpegAudioControl) this.mediaPlayer.getPlayer().getControl(MpegAudioControl.class.getName());

		if (fcMpeg == null) {
		} else {
			this.panelGlobal.add(fcMpeg.getControlComponent());
		}
		System.out.println("getFormat " + format);
		return format;
	}

	protected void changeVolume() {
		int vSlider = this.sliderVolume.getValue();
		float v = vSlider / 100.0f;
		this.mediaPlayer.getPlayer().getGainControl().setLevel(v);

	}

	public DataSource getDataSource() {
		DataSource ds  = ((SourceCloneable) this.dataSource).createClone();
		return ds;
	}

	class ThreadPosition implements Runnable {
		boolean updatePosition = true;
		boolean running = true;

		ThreadPosition() {
			Thread t = new Thread(this);
			t.start();
		}

		public void stop() {
			running = false;
			if (mediaPlayer == null) {
			} else {
				mediaPlayer.stopAndDeallocate();
			}
		}

		@Override
		public void run() {
			openMediaPlayer();
			while (true) {
				try {
					Thread.sleep(500);
					if (mediaPlayer == null) {

					} else {
						if (updatePosition) {
							Player player = mediaPlayer.getPlayer();
							if (player == null) {
							} else {
								double dureeTotale = player.getDuration().getSeconds();
								double time = player.getMediaTime().getSeconds();
								// System.out.println(" mediaPLayer "+player.getMediaTime().getSeconds()+" : "+player.getDuration().getSeconds()+"  s ");
								int valueSliderPosition = (int) ((time * 100) / dureeTotale);
								sliderPosition.setValue(valueSliderPosition);
							}
						}
					}
				} catch (InterruptedException e) {
				} catch (Exception e) {

					e.printStackTrace();
				}
			}

		}

		public void setUpdatePosition(boolean updatePosition) {
			this.updatePosition = updatePosition;
		}
	}

}
